package com.codeanalysissys.backend.golang;

import com.codeanalysissys.backend.graphs.pdg.ControlDependenceGraph;
import com.codeanalysissys.backend.graphs.pdg.DataDependenceGraph;
import com.codeanalysissys.backend.graphs.pdg.ProgramDependeceGraph;
import com.codeanalysissys.backend.java.JavaDDGBuilder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * Program Dependence Graph (PDG) builder for Java programs.
 * A Golang parser generated via ANTLRv4 is used for this purpose.
 * This implementation is based on ANTLRv4's Visitor pattern.
 *
 * @author Huang WeiQuan
 */
public class GoPDGBuilder {

    /**
     * Builds and returns Program Dependence Graphs (PDG) for each given Java file.
     */
    public static ProgramDependeceGraph[] buildForAll(String[] javaFilePaths) throws IOException {
        File[] goFiles = new File[javaFilePaths.length];
        for (int i = 0; i < goFiles.length; ++i)
            goFiles[i] = new File(javaFilePaths[i]);
        return buildForAll(goFiles);
    }

    /**
     * Builds and returns Program Dependence Graphs (PDG) for each given Java file.
     */
    public static ProgramDependeceGraph[] buildForAll(File[] goFiles) throws IOException {

        ControlDependenceGraph[] ctrlSubgraphs;
        ctrlSubgraphs = new ControlDependenceGraph[goFiles.length];
        for (int i = 0; i < goFiles.length; ++i)
            ctrlSubgraphs[i] = GoCDGBuilder.build(goFiles[i]);

        DataDependenceGraph[] dataSubgraphs;
        dataSubgraphs = GoDDGBuilder.buildForAll(goFiles);

        // Join the subgraphs into PDGs
        ProgramDependeceGraph[] pdgArray = new ProgramDependeceGraph[goFiles.length];
        for (int i = 0; i < goFiles.length; ++i) {
            pdgArray[i] = new ProgramDependeceGraph(goFiles[i].getName(),
                    ctrlSubgraphs[i], dataSubgraphs[i]);
        }

        return pdgArray;
    }

    public static ProgramDependeceGraph buildForAll(String fileName, InputStream inputStream) throws IOException {
        DataDependenceGraph dataSubgraphs;
        dataSubgraphs = GoDDGBuilder.buildForOne(fileName, inputStream);
        ProgramDependeceGraph pdgArray = new ProgramDependeceGraph(fileName, null, dataSubgraphs);
        return pdgArray;
    }

    public static ProgramDependeceGraph build(InputStream content) throws IOException {
        return new ProgramDependeceGraph(GoCDGBuilder.build(content), GoDDGBuilder.build(content));
    }
}
